/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package coalescent.cef.phylo;

import coalescent.data.K69Data;

import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.CrossoverScalingControl;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
import edu.uci.ics.jung.visualization.layout.PersistentLayout;

import org.openide.awt.StatusDisplayer;

import static coalescent.phylogeny.GeneTree.Edge;
import static coalescent.phylogeny.GeneTree.Node;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;

import javax.swing.*;

/**
 * Creates GUI to display gene tree. It contains the following controls:
 * <ol>
 *     <li>genetree</li>
 *     <li>zoom function</li>
 *     <li>pick/transform modes</li>
 *     <li>save layout</li>
 * </ol>
 *
 * @since since
 * @version version
 * @author Susanta Tewari
 * @history Created on Oct 15, 2013.
 */
public class GeneTreeDrawer_Editor extends GeneTreeDrawer_Base {

    private String layoutPath;
    private final PersistentLayout<Node, Edge> layout;

    /**
     * @param data infinite-sites data
     * @param layoutPath file to store tree layout; may be {@code null}
     */
    public GeneTreeDrawer_Editor(K69Data data, String layoutPath) {

        super(data);

        layout          = new JUNG_PLayoutImpl_NodeLabel(tree, super.layout);
        this.layoutPath = layoutPath;
    }

    public JComponent draw() {
        return decorateViewer(getViewer());
    }

    private JPanel decorateViewer(final VisualizationViewer<Node, Edge> vv) {


        // mouse: modes & zoom
        final GraphZoomScrollPane zoomPanel     = new GraphZoomScrollPane(vv);    // zoom
        final DefaultModalGraphMouse graphMouse = new DefaultModalGraphMouse();    // mouse
        final JComboBox modeBox                 = graphMouse.getModeComboBox();    // mouse modes

        vv.setGraphMouse(graphMouse);
        modeBox.addItemListener(graphMouse.getModeListener());
        graphMouse.setMode(ModalGraphMouse.Mode.PICKING);


        // fit screen
        final double factor         = (vv.getSize().getWidth()) / layout.getSize().getWidth();
        final JScrollBar hScrollBar = zoomPanel.getHorizontalScrollBar();

        new CrossoverScalingControl().scale(vv, (float) factor, vv.getCenter());
        hScrollBar.setValue(hScrollBar.getMaximum());


        // layout: save & restore
        layout.setGraph(forest);

        final JButton persist       = new JButton("Save Layout");
        final JButton restore       = new JButton("Restore Layout");
        final boolean layout_exists = new File(layoutPath).exists();

        persist.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                try {

                    layout.persist(layoutPath);

                    if (!restore.isEnabled()) restore.setEnabled(true);

                } catch (IOException e1) {
                    throw new RuntimeException(e1);
                }
            }

        });
        restore.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                try {
                    layout.restore(layoutPath);
                } catch (Exception e1) {

                    e1.printStackTrace();
                    restore.setEnabled(false);
                    StatusDisplayer.getDefault().setStatusText("Restore failed -> disabled.");
                }
            }

        });


        // initial restore
        if (layout_exists) {

            try {
                restore.doClick();
            } catch (Exception e) {    // fails (but layout is not corrupted)

                new File(layoutPath).delete();    // remove file
                restore.setEnabled(false);    // restore disabled (gets enabled after persist)
            }
        }


        // collect all the controls
        final JToolBar controls = new JToolBar();

        controls.add(modeBox);
        controls.add(persist);
        controls.add(restore);


        // add the controls
        final JPanel geneTreeVisualComp = new JPanel(new BorderLayout());

        geneTreeVisualComp.add(controls, BorderLayout.PAGE_START);
        geneTreeVisualComp.add(zoomPanel, BorderLayout.CENTER);
        addComponents(geneTreeVisualComp);

        return geneTreeVisualComp;
    }

    /**
     * Extensions can add more components to the end panel.
     *
     * @param master the end component returned by {@link #draw()}
     */
    protected void addComponents(JPanel master) {}
}
